<template></template>

<script>
import model_pipes from "./model_pipes.json";
import model_junction from "./model_junction.json";
import model_valves from "./model_valves.json";
import model_reservoirs from "./model_reservoirs.json";
import { pipe_flow, pipe_id } from "./pipes_flow";

let valveList = new Dictionary();
let flowList = new Dictionary();

//创建字典类
function Dictionary() {
  var items = {};
  //set(key,value)向字典里添加新元素，这里主要用来添加边
  this.set = function (key, value) {
    items[key] = value;
  };
  //has(key)如果存在就返回true，否则false
  this.has = function (key) {
    return key in items;
  };
  //get(key)通过key查找特定的数值并返回，这里主要用来查找顶点对应的边数组
  this.get = function (key) {
    return this.has(key) ? items[key] : undefined;
  };
}

//创建图类Graph()
function Graph() {
  var vertices = []; //用来储存顶点
  var adjList = new Dictionary(); //用来储存边
  var valveList = new Dictionary(); //用来储存阀门的起始节点和终止节点
  //创建initializeColor用来初始化各个顶点的颜色，为遍历过程中的标记做准备
  var initializeColor = function () {
    var color = [];
    for (var i = 0; i < vertices.length; i++) {
      color[vertices[i]] = "white";
    }
    return color;
  };
  //addVertex(key)用来添加顶点
  this.addVertex = function (v) {
    vertices.push(v);
    adjList.set(v, []);
  };
  //addEdge(key,value)用来添加边v-w
  this.addEdge = function (v, w) {
    adjList.get(v).push(w);
    adjList.get(w).push(v);
  };
  this.addValve = function (v, w) {
    valveList.set(v, w);
    valveList.set(w, v);
  };
  //toString()把邻接表转化成字符串的形式，便于输出显示
  this.toString = function () {
    var s = "";
    for (var i = 0; i < vertices.length; i++) {
      s += vertices[i] + "->";
      var neighbors = adjList.get(vertices[i]);
      for (var j = 0; j < neighbors.length; j++) {
        s += neighbors[j] + " ";
      }
      s += "\n";
    }
    return s;
  };
  //广度优先遍历，在Graph()类中添加以下方法
  this.bfs = function (v, callback) {
    var color = initializeColor(); //初始化节点，都标记为白色
    var queue = []; //创建队列用来顶点的入队；
    queue.push(v); //访问的节点入队列
    while (!queue.length == 0) {
      //如果队列非空就执行以下
      var u = queue.shift(); //节点出队列
      var neighbors = adjList.get(u); //探索节点对应的边
      color[u] = "grey"; //把搜索过的节点变成灰色
      for (var i = 0; i < neighbors.length; i++) {
        var w = neighbors[i];
        if (color[w] === "white") {
          //如果探索到的子节点是白色就逐一变灰并入队列
          color[w] = "grey";
          queue.push(w);
        }
      }
      color[u] = "black"; //节点完成搜索和探索的过程，直接变黑
      if (callback) {
        callback(u); //回调函数，可以用来输出
      }
    }
  };
  this.BFS = function (v) {
    var color = initializeColor(),
      queue = [],
      d = [], //用来储存从v到u的距离
      pred = []; //用来储存节点的前溯点
    queue.push(v);
    for (var i = 0; i < vertices.length; i++) {
      d[vertices[i]] = 0; //初始化
      pred[vertices[i]] = null;
    }
    while (!queue.length == 0) {
      var u = queue.shift();
      var neighbors = adjList.get(u);
      color[u] = "grey";
      for (i = 0; i < neighbors.length; i++) {
        var w = neighbors[i];
        if (color[w] === "white") {
          color[w] = "grey";
          d[w] = d[u] + 1; //从头节点到w的距离
          pred[w] = u;
          queue.push(w);
        }
      }
      color[u] = "black";
    }
    return {
      distance: d,
      predecessers: pred,
    };
  };
}

var graph = new Graph();

for (let i = 0; i <= pipe_id.length - 1; i++) {
  flowList.set(pipe_id[i], pipe_flow[i]);
}

model_junction.forEach((item) => {
  graph.addVertex(item.CODE);
});

model_reservoirs.forEach((item) => {
  graph.addVertex(item.CODE);
});

model_pipes.forEach((item) => {
  graph.addEdge(item.STARTNODE, item.ENDNODE);
});

model_valves.forEach((item) => {
  graph.addEdge(item.STARTNODE, item.ENDNODE);
  valveList.set(item.STARTNODE, item.CODE);
  valveList.set(item.ENDNODE, item.CODE);
});

//bfs实例
// function printNode(value) {
//     console.log("Visited vertex:" + value);
// }
// graph.bfs("JGIS434567", printNode);

//BFS实例
var fromVertex = "JGIS395579";
var shortestPath = graph.BFS(fromVertex);
//搜索路径BFS
var allPath = [];
var valveVisited = new Dictionary();
for (var i = 1; i < model_junction.length; i++) {
  var toVertex = model_junction[i].CODE;
  var path = []; //path用来储存路径
  for (var v = toVertex; v !== fromVertex; v = shortestPath.predecessers[v]) {
    path.push(v);
  }
  path.push(fromVertex);
  var s = path.pop();
  var length = 0;
  let res = [];
  res.push(s);
  while (!path.length == 0) {
    let w = path.pop();
    res.push(w);
    length += 1;
    if (valveList.has(w)) {
      if (valveVisited.get(w) != length) {
        allPath.push(res);
      }
      valveVisited.set(w, length);
      break;
    }
  }
}

console.log(allPath);
</script>
